#!/usr/bin/env python
#coding:utf-8
import findipfromdns
import multiprocessing
import time
import sys
import urllib2
import re

def getip(dnsserver, subdomain, banip):
   	#调用findipfromdns获取ip
	ip = findipfromdns.findipfromdns(dnsserver, subdomain)
	if (ip != banip and ip != []):
		return (dnsserver, subdomain, ip)
	else:
		return (dnsserver, subdomain, "can't find")

def getsubfromlinks(domain):
    	#通过links接口获取子域名
	url = 'http://i.links.cn/subdomain/'
	data = 'domain=%s&b2=1&b3=1&b4=1'%domain
	req = urllib2.Request(url = url, data = data)
	req = urllib2.urlopen(req)
	domainlist = re.compile(r'\.<a href="(\S*?)" rel=nofollow target=_blank>(\S*?)</a></div>').findall( req.read() )
	resu = []
	for subdomain in domainlist:
		resu.append(subdomain[0].replace('http://','').replace('https://','').replace('.'+domain,''))
	return resu

def geterrorip(allsubdomains):
	#错误ip
	allip = {}
	for info in allsubdomains:
		ip = str(info[2])
		if ip in allip:
			allip[ip] += 1
		else:
			allip[ip] = 1
	errorip = []
	for ip in allip:
		if allip[ip] > 100:
			errorip.append(ip)
	return errorip

def fuzzonedomain(domain, dicname, links):
	stime = time.time()
	print '\nNow fuzzing domain is  '+domain
	dnslist = ["223.5.5.5", "223.6.6.6", "180.76.76.76"]
	f = open(dicname)
	sdic = f.read().split('\n')
	f.close()
    	#将links获取的子域名和字典的子域名合并
    	if links == True:
		resu = getsubfromlinks(domain)

	else:
		resu = []
	dic = list(set(resu + sdic))
    	#排除泛解析
	banip = 'time out'
	while(banip == 'time out'):
		try:
			banip = findipfromdns.findipfromdns(dnslist[0],'an9xm02d.'+domain)
		except:
			banip = 'time out'

    	#开始多进程
	resultlist = []
	pool = multiprocessing.Pool(processes = 90)
	for i in xrange(len(dic)):
		n = i % len(dnslist) - 1
		subdomain = dic[i] + '.' + domain
		resultlist.append(pool.apply_async(getip, (dnslist[n], subdomain, banip)))
	pool.close()
	pool.join()
    	#处理结果 并 输出
	allsubdomains = []
	errornum = 0
	for res in resultlist:
		try:
			resp =  res.get()
			if "can't find" not in resp:
				allsubdomains.append(resp)
		except Exception, e:
			errornum = errornum + 1	
	if len(allsubdomains)==0:
		print "Use time is %s  ,  Find %s subdoamins , Error number is %s"%(time.time() - stime, len(allsubdomains), errornum)
		return allsubdomains
	
	errorip = geterrorip(allsubdomains)

	print 'Subdomains:'
	allsubdomains2 = []
	for sub in allsubdomains:
		if str(sub[2]) not in errorip:
			print sub
			allsubdomains2.append(sub)	
	print "     "
	print "Use time is %s  ,  Find %s subdoamins , Error number is %s"%(time.time() - stime, len(allsubdomains2), errornum)
	return allsubdomains2

if __name__ == '__main__':
	if len(sys.argv) == 1:
		print 'e.g. python fuzz.py ly.com'
		exit()
	else:
		domain = sys.argv[1]
    	#二级域名
	subs =  fuzzonedomain(domain, 'dic', True)
    	#三级域名
	for subinfo in subs:
		fuzzonedomain(subinfo[1], 'sdic', False)